#ifndef GAUSS_LEGENDRE_H_
#define GAUSS_LEGENDRE_H_

#include "general.h"

typedef struct
{
    int i;          /* Número de iterações */
    mpf_t a[3];     /* Variáveis a, b, t, p de acordo com o pipeline */
    mpf_t b[3];
    mpf_t t[2];
    mpf_t p[3];
    mpf_t pi[2];    /* Pi (antigo e atual para convergência) */
    int stop;       /* B_TRUE se convergiu */
} gl_param; /* Parâmetros para Gauss-Legendre concorrente */


/* Valores iniciais para o método de Gauss-Legendre */
void gl_init_values(mpf_t a, mpf_t b, mpf_t t, mpf_t p);

/* Inicializa estrutura paralela */
void gl_init_param(gl_param *p);

/* Limpa estrutura paralela */
void gl_clear_param(gl_param *p);

/* Realiza o cálculo de a */
void gl_a_value(mpf_t a1, mpf_t a0, mpf_t b0);

/* Realiza o cálculo de b */
void gl_b_value(mpf_t b1, mpf_t a0, mpf_t b0);

/* Realiza o cálculo de t */
void gl_t_value(mpf_t t1, mpf_t t0, mpf_t p0, mpf_t a0, mpf_t a1);

/* Realiza o cálculo de p */
void gl_p_value(mpf_t p1, mpf_t p0);

/* Realiza o cálculo de Pi */
void gl_pi_value(mpf_t pi, mpf_t a, mpf_t b, mpf_t t);

/* Método de Gauss-Legendre sequêncial */
void gauss_legendre(mpf_t pi, long *it);

/* Método de Gauss-Legendre concorrente */
void gauss_legendre_conc(mpf_t pi, long *it);

/* Gauss-Legendre Thread para cálculo de a */
void *glt_calculate_a(void *arg);

/* Gauss-Legendre Thread para cálculo de b */
void *glt_calculate_b(void *arg);

/* Gauss-Legendre Thread para cálculo de t */
void *glt_calculate_t(void *arg);

/* Gauss-Legendre Thread para cálculo de p */
void *glt_calculate_p(void *arg);

/* Gauss-Legendre Thread para cálculo de Pi */
void *glt_calculate_pi(void *arg);

#endif /* GAUSS_LEGENDRE_H_ */
